﻿#region NeoPatterns
// 
// NeoPatterns framework is released under LGPLv3 license.
// See http://www.opensource.org/licenses/lgpl-3.0.html for more details.
// 
// Please visit http://neopatterns.wikidot.com for more information about NeoPatterns
// 
// Copyright (c) Pascal Craponne 2008
// 
#endregion

using System;
using System.Text.RegularExpressions;

namespace NeoPatterns.Utility
{
    /// <summary>
    /// Determines if name matches the provided pattern.
    /// Supports start and/or ending "*" or Regex values
    /// </summary>
    public class NameMatcher
    {
        public string Expression { get; private set; }

        protected string NameStartsWith { get; private set; }
        protected string NameEndsWith { get; private set; }
        protected string NameContains { get; private set; }
        protected Regex NameRegex { get; private set; }

        public const string Wildcard = "*";

        /// <summary>
        /// Tests match with given name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public bool Matches(string name)
        {
            var comparisonType = StringComparison.InvariantCulture;
            if (NameStartsWith != null && !name.StartsWith(NameStartsWith, comparisonType))
                return false;
            if (NameEndsWith != null && !name.EndsWith(NameEndsWith, comparisonType))
                return false;
            if (NameContains != null && !name.Contains(NameContains))
                return false;
            if (NameRegex != null && !NameRegex.Match(name).Success)
                return false;
            return true;
        }

        public NameMatcher(string expression)
        {
            Expression = expression;
            var comparisonType = StringComparison.InvariantCulture;
            if (expression.Length > 1 && expression.EndsWith(Wildcard, comparisonType)
                && expression.StartsWith(Wildcard, comparisonType))
                NameContains = expression.Substring(1, expression.Length - 2);
            else if (expression.StartsWith(Wildcard, comparisonType))
                NameEndsWith = expression.Substring(1);
            else if (expression.EndsWith(Wildcard, comparisonType))
                NameStartsWith = expression.Substring(0, expression.Length - 1);
            else
                NameRegex = new Regex(expression, RegexOptions.Compiled);
        }
    }
}
